﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using EnsureThat;

namespace Robo
{
	/// <summary>
	/// A compound comparer.
	/// </summary>
	/// <typeparam name="T">The type to compare.</typeparam>
	[ComVisible(false)]
	public sealed class CompoundComparer<T> : Comparer<T>
	{
		/// <summary>
		/// First comparer.
		/// </summary>
		public readonly IComparer<T> First;
		/// <summary>
		/// Second comparer.
		/// </summary>
		public readonly IComparer<T> Second;
		/// <summary>
		/// Compares two T objects.
		/// </summary>
		public override int Compare(T x, T y)
		{
			var res = First.Compare(x, y);
			if (res != 0)
				return res;
			return Second.Compare(x, y);
		}
		/// <summary>
		/// Initializes a compound comparer, using two comparers.
		/// </summary>
		public CompoundComparer(IComparer<T> first, IComparer<T> second)
		{
			this.First = first;
			this.Second = second;
		}
		/// <summary>
		/// Chains the comparers, recursively.
		/// </summary>
		/// <param name="comparers">The comparers.</param>
		public CompoundComparer(params IComparer<T>[] comparers)
		{
			Ensure.That(() => comparers, Is.NotNull, CollectionIs.HasAtLeast<IComparer<T>>(3));
			First = comparers.First();
			if (comparers.Skip(1).Count() > 2)
				Second = new CompoundComparer<T>(comparers.Skip(1).ToArray());
			else
				Second = new CompoundComparer<T>(comparers[1], comparers[2]);
		}
	}
}
